home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
games_du
/
d3dlvedt.zip
/
DN3D-DC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-14
|
25KB
|
987 lines
// duke hack- compile/decomile .grp/.art files
//
// Format for PALETTE.DAT file:
//
// 768 system palette
// 2 number of ppalette lookup tables
// 256 palette lookup table
// ...
//
// format for *.ART file:
//
// 4 ??? (1)
// 4 ???
// 4 ???
// 4 ???
//
// 512 256 widths (int)
// 512 256 height (int)
// 512 ??? (int)
// 512 ??? (int)
//
//
// compiled using huge model
//
// syntax:
//
// DN3D-DC <command> <grp/art file> <directory>
//
// commands:
//
// DG : decompile individual files to directory and create GRP.LST
//
// CG : compile grp file from individual files in directory using GRP.LST (also backup old GRP file)
//
// DA : decompile individual files to directory and create TILES0??.LST file
//
// CA : compile art file from individual files in directory using TILES0??.LST file
// includes...
#include <alloc.h>
#include <conio.h>
#include <ctype.h>
#include <dir.h>
#include <mem.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// defines...
// booleans
#define FALSE 0
#define TRUE 1
// commands
#define CMD_DECOMPGRP 0
#define CMD_DECOMPART 1
#define CMD_COMPGRP 2
#define CMD_COMPART 3
// typedef...
typedef struct
{
char szLabel[12];
long nSize;
} DIRATOM, far* LPDIRATOM;
typedef struct
{
char szID[2];
long nFileSize;
long nReserved;
long nHeaderSize;
long nInfoSize;
long nWidth;
long nHeight;
short nPlanes;
short nBits;
long nCompression;
long nImageSize;
long xPelsPerMeter;
long yPelsPerMeter;
long nClrUsed;
long nClrImportant;
} BMPHEADER;
typedef struct
{
char nBlue;
char nGreen;
char nRed;
char nFilter;
} RGBQUAD;
typedef struct
{
char nRed;
char nGreen;
char nBlue;
} RGBART;
typedef struct
{
char nIdx[256];
} LUTART, far* LPLUTART;
// global info...
int nCmd;
char szCommand[MAXPATH]; // the command
char szGrpPath[MAXPATH]; // the full grp/art file name
char szGrpDrive[MAXDRIVE]; // subpart of szGrpPath
char szGrpDir[MAXDIR]; // subpart of szGrpPath
char szGrpName[MAXFILE]; // subpart of szGrpPath
char szGrpExt[MAXEXT]; // subpart of szGrpPath
char szDirPath[MAXPATH]; // when the stuff goes/is
RGBART pSysPal[256]; // system palette
short nPalLUT; // number of palette lookup tables
LPLUTART lpPalLUT; // pointer to palette lookup tables
long aArtHeader[4]; // the first 16 bytes of an art file.
short anWidth[256]; // the widths
short anHeight[256]; // the heights
short anVal1[256]; // unknown for now
short anVal2[256]; // unknown for now
char pTempBuff[640]; // temp buffer
// prototypes...
void PrintInfo(void);
void PrintHelp(void);
int DecompileGrp(void);
int DecompileArt(void);
int CompileArt(void);
int CompileGrp(void);
extern unsigned _stklen = 16768u;
// the functions...
int main(int nArgs, char* aszArg[])
{
// a little info...
PrintInfo();
//we running with 4 arguments?
if (nArgs != 4)
{
PrintHelp();
return -1;
}
// get arguments.
strcpy(szCommand, aszArg[1]);
strupr(szCommand);
strcpy(szGrpPath, aszArg[2]); // grp [drive:][\directory\]filename.ext
fnsplit(szGrpPath, szGrpDrive, szGrpDir, szGrpName, szGrpExt);
strcpy(szDirPath, aszArg[3]); // destination [drive:][\directory[\]]
if (!strcmp(szCommand, "DG"))
nCmd = CMD_DECOMPGRP;
else if (!strcmp(szCommand, "DA"))
nCmd = CMD_DECOMPART;
else if (!strcmp(szCommand, "CG"))
nCmd = CMD_COMPGRP;
else if (!strcmp(szCommand, "CA"))
nCmd = CMD_COMPART;
else
{
// bad command
PrintHelp();
return -1;
}
// be sure there is no / on end of dir
if (szDirPath[strlen(szDirPath) - 1] == '\\')
szDirPath[strlen(szDirPath) - 1] = '\0';
// branch to do the tasks
switch (nCmd)
{
case CMD_COMPGRP:
// compile art file
printf("Compiling %s...\n", szGrpPath);
if (!CompileGrp())
{
printf("Error in compiling\n");
return -1;
}
break;
case CMD_COMPART:
// compile art file
printf("Compiling %s...\n", szGrpPath);
if (!CompileArt())
{
printf("Error in compiling\n");
return -1;
}
break;
case CMD_DECOMPART:
// decompile art file
printf("Decompiling %s...\n", szGrpPath);
if (!DecompileArt())
{
printf("Error in decompiling\n");
return -1;
}
break;
case CMD_DECOMPGRP:
// decompile grp file
printf("Decompiling %s...\n", szGrpPath);
if (!DecompileGrp())
{
printf("Error in decompiling\n");
return -1;
}
break;
default:
// we shouldn't get in here!
PrintHelp();
return -1;
}
return 0;
}
void PrintInfo(void)
{
printf("┌┬┬──────────────────────────────────────────────────────────────────┬┬┐\n");
printf("│││ Duke Nukem 3D Decompiler/Compiler Version 1.1 │││\n");
printf("│││ GRP/ART file compiler/decompiler for Duke Nukem 3D 1.1 shareware │││\n");
printf("│││ Written By Daniel Mecklenburg Jr, codewar@ns.cencom.net │││\n");
printf("└┴┴──────────────────────────────────────────────────────────────────┴┴┘\n");
}
void PrintHelp(void)
{
printf("\n"
"Syntax:\n"
" DN3D-DC <command> <file> <directory>\n"
"\n"
"Commands:\n"
" DG : decompile individual files from grp file to directory and create .LST\n"
" CG : backup/compile grp file from individual files in directory using .LST\n"
" DA : decompile individual files from art file to directory and create .LST\n"
" CA : backup/compile art file from individual files in directory using .LST\n"
"\n"
"Examples:\n"
" DN3D-DC DG DUKE3D.GRP F:\\DUKERES\\ : will extract all files in DUKE3D.GRP\n"
" and place them in F:\\DUKERES\\ (ending \\ on directories are optional).\n"
" A text file called DUKE3D.LST will be created containing the GRP's\n"
" packing list.\n"
" DN3D-DC DA TILES000.ART F:\\DUKERES\\ : will extract all graphics from\n"
" TILES000.ART and save them as BMP's in F:\\DUKERES\\ named 000-000.BMP\n"
" though 000-255.BMP. A text file called TILES000.LST will be created\n"
" containing the ART's packing list.\n"
" DN3D-DC CA G:\\STUFF\\TILES000.ART E:\\BMPS : will create TILES000.ART\n"
" from the TILES000.LST and BMP files located in E:\\BMP.\n");
}
char* szComplete = "Completed! \n";
char* szAbort = "Aborted! \n";
int DecompileGrp(void)
{
// decompile the grp file (szGrpPath) to directory (szDirPath)
FILE* pFile; // the .grp file
FILE* pOutFile; // the grp.lst file
FILE* pResFile; // the individual files
char pStr[13]; // holds the ken tag
long nDirSize; // entries in directory
LPDIRATOM lpDir; // pointer to the dir list
char szFilename[MAXPATH]; // filename work
int nIdx; // dir index
long nIdx2; // file byte index
int c; // a byte read/written
char* pDoneMsg = szComplete;
// open the grp file...
if ((pFile = fopen(szGrpPath, "rb")) == NULL)
{
printf("Could not open %s.\n", szGrpPath);
return FALSE;
}
// get/check the tag
if (fread(pStr, 12, 1, pFile) != 1)
{
printf("Error reading %s.\n", szGrpPath);
fclose(pFile);
return FALSE;
}
pStr[12] = '\0';
if (strcmp(pStr, "KenSilverman") != 0)
{
printf("%s is not a DukeNukem3d grp file.\n", szGrpPath);
fclose(pFile);
return FALSE;
}
// get number of entries
if (fread(&nDirSize, sizeof (long), 1, pFile) != 1)
{
printf("I/O error.\n");
fclose(pFile);
return FALSE;
}
// allocate directory structure
if ((lpDir = farmalloc(16 * (size_t)nDirSize)) == NULL)
{
printf("Out of memory.\n");
fclose(pFile);
return FALSE;
}
// read directory in
for (nIdx = 0; nIdx < nDirSize; nIdx++)
{
if (fread(&lpDir[nIdx], sizeof (DIRATOM), 1, pFile) != 1)
{
printf("I/O error.\n");
farfree(lpDir);
fclose(pFile);
return FALSE;
}
}
// create .LST file
sprintf(szFilename, "%s\\%s.LST", szDirPath, szGrpName);
if ((pOutFile = fopen(szFilename, "w")) == NULL)
{
printf("Could not create %s file.\n", szFilename);
farfree(lpDir);
fclose(pFile);
return FALSE;
}
for (nIdx = 0; nIdx < nDirSize; nIdx++)
{
_fmemcpy(pStr, lpDir[nIdx].szLabel, 12);
pStr[12] = '\0';
fprintf(pOutFile, "%s\n", pStr);
printf("%s \r", pStr);
// create this resource file
sprintf(szFilename, "%s\\%s", szDirPath, pStr);
if ((pResFile = fopen(szFilename, "wb")) == NULL)
{
printf("Could not create %s.\n", pStr);
farfree(lpDir);
fclose(pFile);
fclose(pOutFile);
return FALSE;
}
for (nIdx2 = 0; nIdx2 < lpDir[nIdx].nSize; nIdx2++)
{
if ((c = fgetc(pFile)) == EOF)
{
printf("Unexpected EOF.\n");
farfree(lpDir);
fclose(pFile);
fclose(pOutFile);
return FALSE;
}
if (fputc(c, pResFile) == EOF)
{
printf("Unable to write to %s.\n", pStr);
farfree(lpDir);
fclose(pFile);
fclose(pOutFile);
return FALSE;
}
}
fclose(pResFile);
if (kbhit())
{
if (getch() == 27)
{
pDoneMsg = szAbort;
break;
}
}
}
printf(pDoneMsg);
fclose(pOutFile);
// free directory
farfree(lpDir);
// and close the file...
fclose(pFile);
return TRUE;
}
int DecompileArt(void)
{
// decompile the art file (szGrpPath) to directory (szDirPath)
long nImageSize;
long nPalSize;
long nRasterSize; // size of raster
FILE* pFile; // the .grp file
FILE* pOutFile; // the grp.lst file
FILE* pResFile; // the individual files
FILE* pPalFile; // the palette.dat file
char szFilename[MAXPATH]; // filename work
char szBMPName[MAXPATH]; // BMP filename
char szPalName[MAXPATH]; // Palette filename
int nIdx; // dir index
int nIdx2; // file byte index
int nRow, nCol; // bitmap index
RGBQUAD rgb; // a BMP palette entry
BMPHEADER bmpHeader; // header for bmp file
char huge* lpBitmap; // the bitmap image read in
char huge* lp; // temp pointer
char* pDoneMsg = szComplete;
// open the art file...
if ((pFile = fopen(szGrpPath, "rb")) == NULL)
{
printf("Could not open %s.\n", szGrpPath);
return FALSE;
}
// get header
if (fread((void*)aArtHeader, sizeof (long), 4, pFile) < 4)
{
printf("Error reading %s.\n", szGrpPath);
fclose(pFile);
return FALSE;
}
// read widths/heights/other info
if (fread(anWidth, sizeof (short), 256, pFile) < 256)
{
printf("I/O error.\n");
fclose(pFile);
return FALSE;
}
if (fread(anHeight, sizeof (short), 256, pFile) < 256)
{
printf("I/O error.\n");
fclose(pFile);
return FALSE;
}
if (fread(anVal1, sizeof (short), 256, pFile) < 256)
{
printf("I/O error.\n");
fclose(pFile);
return FALSE;
}
if (fread(anVal2, sizeof (short), 256, pFile) < 256)
{
printf("I/O error.\n");
fclose(pFile);
return FALSE;
}
// go fetch the palette. must be called palette.dat and in the destination with the tiles.art file
sprintf(szPalName, "%sPALETTE.DAT", szGrpDir);
if ((pPalFile = fopen(szPalName, "rb")) == NULL)
{
printf("Unable to open palette file. Must reside with ART file.\n");
fclose(pFile);
return FALSE;
}
// read the main system palette
if (fread(pSysPal, sizeof (RGBART), 256, pPalFile) < 256)
{
printf("I/O error.\n");
fclose(pFile);
fclose(pPalFile);
return FALSE;
}
// get number of palette look up tables
if (fread(&nPalLUT, sizeof (short), 1, pPalFile) < 1)
{
printf("I/O error.\n");
fclose(pFile);
fclose(pPalFile);
return FALSE;
}
// allocate and read the pal luts
if ((lpPalLUT = farmalloc(nPalLUT * sizeof (LUTART))) == NULL)
{
printf("Out of memory.\n");
fclose(pFile);
fclose(pPalFile);
return FALSE;
}
if (fread(lpPalLUT, sizeof (LUTART), nPalLUT, pPalFile) < nPalLUT)
{
printf("I/O error.\n");
farfree(lpPalLUT);
fclose(pFile);
fclose(pPalFile);
return FALSE;
}
fclose(pPalFile);
// create .LST file
sprintf(szFilename, "%s\\%s.LST", szDirPath, szGrpName);
if ((pOutFile = fopen(szFilename, "w")) == NULL)
{
printf("Could not create %s file.\n", szFilename);
fclose(pFile);
return FALSE;
}
// write the header info
fprintf(pOutFile, "%ld %ld %ld %ld\n",
aArtHeader[0], aArtHeader[1], aArtHeader[2], aArtHeader[3]);
for (nIdx = 0; nIdx < 256; nIdx++)
{
// create filename nnn-aaa.bmp where nnn is number (0-255) inside art file and
// aaa is last three digits of tiles???.art filename
if (anWidth[nIdx] && anHeight[nIdx])
{
sprintf(szBMPName, "%03d-%c%c%c.BMP", nIdx, szGrpName[5], szGrpName[6], szGrpName[7]);
fprintf(pOutFile, "%3d %-16s %d %d %d %d\n", nIdx, szBMPName, anWidth[nIdx], anHeight[nIdx], anVal1[nIdx], anVal2[nIdx]);
printf("%3d %s \r", nIdx, szBMPName);
// create this resource file
sprintf(szFilename, "%s\\%s", szDirPath, szBMPName);
if ((pResFile = fopen(szFilename, "wb")) == NULL)
{
printf("Could not create %s.\n", szBMPName);
fclose(pFile);
fclose(pOutFile);
return FALSE;
}
// write bmp header
nRasterSize = anWidth[nIdx];
if (nRasterSize & 0x00000003L)
{
nRasterSize |= 0x00000003L;
nRasterSize++;
}
nImageSize = nRasterSize * (long)anHeight[nIdx];
nPalSize = (long)sizeof (RGBQUAD) * 256L;
_fmemset(&bmpHeader, 0, sizeof (BMPHEADER));
bmpHeader.szID[0] = 'B';
bmpHeader.szID[1] = 'M';
bmpHeader.nFileSize = sizeof (BMPHEADER) + nPalSize + nImageSize;
bmpHeader.nHeaderSize = sizeof (BMPHEADER) + nPalSize;
bmpHeader.nInfoSize = 0x28;
bmpHeader.nWidth = anWidth[nIdx];
bmpHeader.nHeight = anHeight[nIdx];
bmpHeader.nPlanes = 1;
bmpHeader.nBits = 8;
bmpHeader.nImageSize = nImageSize;
if (fwrite(&bmpHeader, sizeof (BMPHEADER), 1, pResFile) < 1)
{
printf("I/O error.\n");
farfree(lpPalLUT);
fclose(pFile);
fclose(pResFile);
return FALSE;
}
// write the palette for this image
for (nIdx2 = 0; nIdx2 < 256; nIdx2++)
{
rgb.nRed = pSysPal[nIdx2].nRed << 2;
rgb.nGreen = pSysPal[nIdx2].nGreen << 2;
rgb.nBlue = pSysPal[nIdx2].nBlue << 2;
rgb.nFilter = 0;
if (fwrite(&rgb, sizeof (RGBQUAD), 1, pResFile) < 1)
{
printf("I/O error.\n");
farfree(lpPalLUT);
fclose(pFile);
fclose(pResFile);
return FALSE;
}
}
// read in the image
if ((lpBitmap = farmalloc((long)anWidth[nIdx] * (long)anHeight[nIdx])) == NULL)
{
printf("Out of memory.\n");
farfree(lpPalLUT);
fclose(pFile);
fclose(pResFile);
return FALSE;
}
lp = lpBitmap;
for (nIdx2 = 0; nIdx2 < anWidth[nIdx]; nIdx2++)
{
if (fread(pTempBuff, anHeight[nIdx], 1, pFile) < 1)
{
printf("Out of memory.\n");
farfree(lpPalLUT);
farfree(lpBitmap);
fclose(pFile);
fclose(pResFile);
return FALSE;
}
_fmemcpy(lp, pTempBuff, anHeight[nIdx]);
lp += (long)anHeight[nIdx];
}
// write the image
for (nRow = anHeight[nIdx] - 1; nRow >= 0; nRow--)
{
for (nCol = 0; nCol < anWidth[nIdx]; nCol++)
{
lp = lpBitmap + ((long)nRow + ((long)nCol * (long)anHeight[nIdx]));
fputc(*lp, pResFile);
}
// put odd bytes on end (BMP rasters must be on a dword boundary
for (; nCol < nRasterSize; nCol++)
fputc(0, pResFile);
}
// close up this bitmap
fclose(pResFile);
farfree(lpBitmap);
}
else if (anWidth[nIdx] || anHeight[nIdx] || anVal1[nIdx] || anVal2[nIdx])
{
// no bitmap, but we have important info...
fprintf(pOutFile, "%3d **************** %d %d %d %d\n", nIdx, anWidth[nIdx], anHeight[nIdx], anVal1[nIdx], anVal2[nIdx]);
}
if (kbhit())
{
if (getch() == 27)
{
pDoneMsg = szAbort;
break;
}
}
}
printf(pDoneMsg);
fclose(pOutFile);
// free palette
farfree(lpPalLUT);
// and close the file...
fclose(pFile);
return TRUE;
}
int CompileArt(void)
{
// compile the art file (szGrpPath) from directory (szDirPath)
long nRasterSize; // size of raster
FILE* pArtFile; // the .art file
FILE* pLstFile; // the .lst file
FILE* pBMPFile; // the individual files
char szLstName[MAXPATH]; // LST filename
char szFilename[MAXPATH]; // filename work
char szBMPName[MAXPATH]; // BMP filename
int nIdx; // dir index
int nNum; // current bitmap number
int nWidth, nHeight; // size of bitmap
int nVal1, nVal2; // the unknown values (they look like bit fields)
int nRow, nCol; // bitmap index
BMPHEADER bmpHeader; // header for bmp file
char huge* lpBitmap; // the bitmap image read in
char huge* lp; // temp pointer
char pBuff[81]; // for reading input from lst
char far* p;
char* pDoneMsg = szComplete;
// open the LST file (in dir)
sprintf(szLstName, "%s\\%s.LST", szDirPath, szGrpName);
if ((pLstFile = fopen(szLstName, "r")) == NULL)
{
printf("Could not open %s file.\n", szLstName);
return FALSE;
}
// read header for art file
fgets(pBuff, 80, pLstFile);
p = _fstrtok(pBuff, " ");
aArtHeader[0] = atol(p);
p = _fstrtok(NULL, " ");
aArtHeader[1] = atol(p);
p = _fstrtok(NULL, " ");
aArtHeader[2] = atol(p);
p = _fstrtok(NULL, " ");
aArtHeader[3] = atol(p);
// get all the values
_fmemset(anWidth, 0, sizeof (short) * 256);
_fmemset(anHeight, 0, sizeof (short) * 256);
_fmemset(anVal1, 0, sizeof (short) * 256);
_fmemset(anVal2, 0, sizeof (short) * 256);
while (fgets(pBuff, 80, pLstFile) != NULL)
{
// get the values
p = _fstrtok(pBuff, " ");
nNum = atoi(p);
p = _fstrtok(NULL, " ");
strcpy(szBMPName, p);
p = _fstrtok(NULL, " ");
nWidth = atoi(p);
p = _fstrtok(NULL, " ");
nHeight = atoi(p);
p = _fstrtok(NULL, " ");
nVal1 = atoi(p);
p = _fstrtok(NULL, " ");
nVal2 = atoi(p);
// set values for this bitmap
anWidth[nNum] = nWidth;
anHeight[nNum] = nHeight;
anVal1[nNum] = nVal1;
anVal2[nNum] = nVal2;
}
rewind(pLstFile);
// remove old backup. rename art file to bak.
sprintf(szFilename, "%s%s%s.BAK",
szGrpDrive, szGrpDir, szGrpName);
remove(szFilename);
rename(szGrpPath, szFilename);
// open the art file
pArtFile = fopen(szGrpPath, "wb");
// write the header/bitmap infos
fwrite(aArtHeader, sizeof (long), 4, pArtFile);
fwrite(anWidth, sizeof (short), 256, pArtFile);
fwrite(anHeight, sizeof (short), 256, pArtFile);
fwrite(anVal1, sizeof (short), 256, pArtFile);
fwrite(anVal2, sizeof (short), 256, pArtFile);
// go though the LST file again and this time move the bitmaps
fgets(pBuff, 80, pLstFile);
while (fgets(pBuff, 80, pLstFile) != NULL)
{
// get the values from the LST file
p = _fstrtok(pBuff, " ");
nNum = atoi(p);
p = _fstrtok(NULL, " ");
strcpy(szBMPName, p);
p = _fstrtok(NULL, " ");
nWidth = atoi(p);
p = _fstrtok(NULL, " ");
nHeight = atoi(p);
p = _fstrtok(NULL, " ");
nVal1 = atoi(p);
p = _fstrtok(NULL, " ");
nVal2 = atoi(p);
printf("%3d %s \r", nNum, szBMPName);
// if it's info w/no bitmap, skip it.
if (!strcmp(szBMPName, "****************"))
continue;
// get the header from the bitmap
sprintf(szFilename, "%s\\%s", szDirPath, szBMPName);
pBMPFile = fopen(szFilename, "rb");
fread(&bmpHeader, sizeof (BMPHEADER), 1, pBMPFile);
// skip over the palette. bitmaps must use duke3d palette. future version
// may best fit bitmaps to duke3d palette.
fseek(pBMPFile, bmpHeader.nHeaderSize, SEEK_SET);
// check size of bitmap. this version of dh will only allow you to replace
// bitmaps with the same size as the original...
if ((bmpHeader.nWidth != nWidth) || (bmpHeader.nHeight != nHeight))
{
printf("Bitmap not the same size as it's original! (%s)\n", szBMPName);
return FALSE;
}
nRasterSize = nWidth;
if (nRasterSize & 0x00000003L)
{
nRasterSize |= 0x00000003L;
nRasterSize++;
}
// read in the bitmap
if ((lpBitmap = farmalloc(bmpHeader.nImageSize)) == NULL)
{
printf("Out of memory.\n");
return FALSE;
}
_fmemset(lpBitmap, 0, (size_t)bmpHeader.nImageSize);
// read in the bitmap (bmps are bottom up)
lp = lpBitmap + ((long)(nHeight - 1) * (long)nRasterSize);
for (nIdx = 0; nIdx < nHeight; nIdx++)
{
if (fread(pTempBuff, (int)nRasterSize, 1, pBMPFile) < 1)
{
printf("I/O error.\n");
return FALSE;
}
_fmemcpy(lp, pTempBuff, (size_t)nRasterSize);
lp -= (long)nRasterSize;
}
fclose(pBMPFile);
// write the bitmap to the art file. stored column wise
for (nCol = 0; nCol < nWidth; nCol++)
{
for (nRow = 0; nRow < nHeight; nRow++)
{
lp = lpBitmap + ((long)nCol + ((long)nRow * (long)nRasterSize));
fputc(*lp, pArtFile);
}
}
farfree(lpBitmap);
if (kbhit())
{
if (getch() == 27)
{
pDoneMsg = szAbort;
break;
}
}
}
printf(pDoneMsg);
fclose(pArtFile);
fclose(pLstFile);
return TRUE;
}
int CompileGrp(void)
{
// Compile the grp file (szGrpPath) to directory (szDirPath)
FILE* pGrpFile; // the .grp file
FILE* pLstFile; // the grp.lst file
FILE* pResFile; // the individual files
char pStr[13]; // holds the ken tag
long nDirSize; // entries in directory
LPDIRATOM lpDir; // pointer to the dir list
char szLstName[MAXPATH]; // filename work
char szResName[MAXPATH]; // filename work
char szFilename[MAXPATH]; // filename work
int nIdx; // dir index
long nIdx2; // file byte index
int c; // a byte read/written
char pBuff[81]; // for reading input from lst
char far* p;
char* pDoneMsg = szComplete;
// open the LST file (in dir)
sprintf(szLstName, "%s\\%s.LST", szDirPath, szGrpName);
if ((pLstFile = fopen(szLstName, "r")) == NULL)
{
printf("Could not open %s file.\n", szLstName);
return FALSE;
}
// count entries
nDirSize = 0;
while (fgets(pBuff, 80, pLstFile) != NULL)
nDirSize++;
rewind(pLstFile);
// allocate directory structure
if ((lpDir = farmalloc(16 * (size_t)nDirSize)) == NULL)
{
printf("Out of memory.\n");
fclose(pLstFile);
return FALSE;
}
// read directory in
for (nIdx = 0; nIdx < nDirSize; nIdx++)
{
// get the name of the file & size
fgets(pBuff, 80, pLstFile);
p = strtok(pBuff, " \n\r");
strupr(p);
_fmemset(&lpDir[nIdx], 0, sizeof (DIRATOM));
strcpy(lpDir[nIdx].szLabel, p);
sprintf(szResName, "%s\\%s", szDirPath, p);
if ((pResFile = fopen(szResName, "rb")) == NULL)
{
printf("Can not open %s.\n", szResName);
fclose(pLstFile);
farfree(lpDir);
return FALSE;
}
fseek(pResFile, 0L, SEEK_END);
lpDir[nIdx].nSize = ftell(pResFile);
fclose(pResFile);
}
fclose(pLstFile);
// remove old backup. rename art file to bak.
sprintf(szFilename, "%s%s%s.BAK",
szGrpDrive, szGrpDir, szGrpName);
remove(szFilename);
rename(szGrpPath, szFilename);
// open the grp file...
if ((pGrpFile = fopen(szGrpPath, "wb")) == NULL)
{
printf("Could not open %s.\n", szGrpPath);
farfree(lpDir);
return FALSE;
}
// write the tag & directory
fwrite("KenSilverman", 12, 1, pGrpFile);
fwrite(&nDirSize, sizeof (long), 1, pGrpFile);
for (nIdx = 0; nIdx < (int)nDirSize; nIdx++)
{
fwrite(&lpDir[nIdx], sizeof (DIRATOM), 1, pGrpFile);
}
// dump the individual files to the grp file
for (nIdx = 0; nIdx < nDirSize; nIdx++)
{
// get name of this resource
_fmemcpy(pStr, lpDir[nIdx].szLabel, 12);
pStr[12] = '\0';
printf("%s \r", pStr);
// open the resource file
sprintf(szResName, "%s\\%s", szDirPath, pStr);
if ((pResFile = fopen(szResName, "rb")) == NULL)
{
printf("Could not open %s.\n", pStr);
farfree(lpDir);
fclose(pGrpFile);
return FALSE;
}
for (nIdx2 = 0; nIdx2 < lpDir[nIdx].nSize; nIdx2++)
{
if ((c = fgetc(pResFile)) == EOF)
{
printf("Unexpected EOF.\n");
farfree(lpDir);
fclose(pResFile);
fclose(pGrpFile);
return FALSE;
}
if (fputc(c, pGrpFile) == EOF)
{
printf("Unable to write to %s.\n", szGrpPath);
farfree(lpDir);
fclose(pResFile);
fclose(pGrpFile);
return FALSE;
}
}
fclose(pResFile);
if (kbhit())
{
if (getch() == 27)
{
pDoneMsg = szAbort;
break;
}
}
}
printf(pDoneMsg);
fclose(pGrpFile);
// free directory
farfree(lpDir);
return TRUE;
}